// 版权所有2009 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package math

// Atan2返回y/x的反正切，使用
// 二者的符号确定返回值的象限
// 。
// 
// 特殊情况如下（按顺序）：
// Atan2（y，NaN）=NaN 
// Atan2（NaN，x）=NaN 
// Atan2（+0，x>=0）=+0 
// Atan2（+0，x<-0）=-Pi 
// Atan2（y<0，0）=-Pi/2 
// Atan2（+Inf，+Inf）=+Pi/4 
// Atan2（-Inf，+Inf）=-Pi/4 
// Atan2（+Inf，-）=3Pi/4 
// Atan2（-Inf，-，-Inf）=-3Pi/4 
// Atan2（y，+Inf 0 
// Atan2（+Inf，x）=+Pi/2 
// Atan2（-Inf，x）=-Pi/2 
func Atan2(y, x float64) float64 {
	if haveArchAtan2 {
		return archAtan2(y, x)
	}
	return atan2(y, x)
}

func atan2(y, x float64) float64 {
	// 特殊情况
	switch {
	case IsNaN(y) || IsNaN(x):
		return NaN()
	case y == 0:
		if x >= 0 && !Signbit(x) {
			return Copysign(0, y)
		}
		return Copysign(Pi, y)
	case x == 0:
		return Copysign(Pi/2, y)
	case IsInf(x, 0):
		if IsInf(x, 1) {
			switch {
			case IsInf(y, 0):
				return Copysign(Pi/4, y)
			default:
				return Copysign(0, y)
			}
		}
		switch {
		case IsInf(y, 0):
			return Copysign(3*Pi/4, y)
		default:
			return Copysign(Pi, y)
		}
	case IsInf(y, 0):
		return Copysign(Pi/2, y)
	}

	// 调用atan并确定象限。
	q := Atan(y / x)
	if x < 0 {
		if q <= 0 {
			return q + Pi
		}
		return q - Pi
	}
	return q
}
